import {
  MDControlController,
  IListEvent,
  IListController,
  IListState,
  IMDControlGroupState,
  CodeListItem,
  MDCtrlLoadParams,
  IToolbarController,
} from '@ibiz-template/runtime';
import { IDEList } from '@ibiz/model-core';
import { ListService } from './list.service';

export class ListController
  extends MDControlController<IDEList, IListState, IListEvent>
  implements IListController
{
  declare service: ListService;

  protected initState(): void {
    super.initState();
    this.state.noSort = this.model.noSort === true;
  }

  protected async onCreated(): Promise<void> {
    await super.onCreated();
    this.service = new ListService(this.model);
    await this.service.init(this.context);
  }

  /**
   * 工具栏
   *
   * @author zk
   * @date 2023-08-02 06:08:34
   * @readonly
   * @type {(IToolbarController | undefined)}
   * @memberof ListController
   */
  protected get batchToolbarController(): IToolbarController | undefined {
    const controller = this.view.getController(
      `${this.model.name!}_batchtoolbar`,
    );
    return controller as IToolbarController;
  }

  /**
   * 工具栏
   *
   * @author zk
   * @date 2023-08-02 06:08:34
   * @readonly
   * @type {(IToolbarController | undefined)}
   * @memberof ListController
   */
  protected get quickToolbarController(): IToolbarController | undefined {
    const controller = this.view.getController(
      `${this.model.name!}_quicktoolbar`,
    );
    return controller as IToolbarController;
  }

  /**
   * 根据数据计算工具栏权限和状态
   *
   * @author zk
   * @date 2023-08-02 06:08:11
   * @param {IData[]} selection
   * @memberof ListController
   */
  setSelection(selection: IData[]): void {
    super.setSelection(selection);
    const data = selection?.[0];
    this.batchToolbarController?.calcButtonState(
      data,
      this.model.appDataEntityId,
    );
    this.quickToolbarController?.calcButtonState(
      data,
      this.model.appDataEntityId,
    );
  }

  /**
   * 加载更多
   * @author lxm
   * @date 2023-05-22 07:33:59
   * @return {*}  {Promise<void>}
   */
  async loadMore(): Promise<void> {
    if (this.state.total > this.state.items.length) {
      await this.load({ isLoadMore: true });
    }
  }

  async afterLoad(args: MDCtrlLoadParams, items: IData[]): Promise<IData[]> {
    await this.handleDataGroup();
    return items;
  }

  /**
   * 设置列表数据
   *
   * @author zk
   * @date 2023-05-26 02:05:46
   * @param {IData[]} items
   * @memberof ListController
   */
  setData(items: IData[]): void {
    this.state.items = items;
  }

  /**
   * 获取列表数据
   *
   * @author zk
   * @date 2023-05-26 02:05:35
   * @return {*}  {IData[]}
   * @memberof ListController
   */
  getAllData(): IData[] {
    return this.state.items;
  }

  /**
   * 处理数据分组
   *
   * @memberof DataViewControlController
   */
  protected async handleDataGroup(): Promise<void> {
    const { enableGroup, groupMode } = this.model;
    if (enableGroup && groupMode) {
      if (groupMode === 'AUTO') {
        this.handleAutoGroup();
      } else if (groupMode === 'CODELIST') {
        await this.handleCodeListGroup();
      }
    }
  }

  /**
   * 处理自动分组
   *
   * @memberof DataViewControlController
   */
  protected handleAutoGroup(): void {
    const { groupAppDEFieldId } = this.model;
    if (groupAppDEFieldId) {
      const { items } = this.state;
      const childrenMap: Map<string, IData[]> = new Map();
      items.forEach((item: IData) => {
        const children = childrenMap.get(item[groupAppDEFieldId]) || [];
        children.push(item);
        childrenMap.set(item[groupAppDEFieldId], children);
      });
      const groups: IMDControlGroupState[] = [];
      childrenMap.forEach((value: IData[], key: string) => {
        groups.push({
          caption: key,
          children: [...value],
        });
      });
      this.state.groups = groups;
    }
  }

  /**
   * 处理代码表分组
   *
   * @memberof DataViewControlController
   */
  protected async handleCodeListGroup(): Promise<void> {
    const { groupAppDEFieldId, groupCodeListId } = this.model;
    if (groupAppDEFieldId && groupCodeListId) {
      const { items } = this.state;
      const groups: IMDControlGroupState[] = [];
      const app = ibiz.hub.getApp(this.context.srfappid);
      const codeList = await app.codeList.get(
        groupCodeListId,
        this.context,
        this.params,
      );
      const keys: string[] = [];
      codeList.forEach((codeListItem: CodeListItem) => {
        const value = items.filter(
          (item: IData) => item[groupAppDEFieldId] === codeListItem.value,
        );
        groups.push({
          caption: codeListItem.text,
          children: [...value],
        });
        keys.push(codeListItem.value as string);
      });
      const otherGroup = items.filter(
        (item: IData) => keys.indexOf(item[groupAppDEFieldId]) === -1,
      );
      if (otherGroup.length > 0) {
        groups.push({
          caption: '其他',
          children: [...otherGroup],
        });
      }
      this.state.groups = groups;
    }
  }
}
